package com.zmn.mcc.business.impl.dept;

import com.zmn.base.channel.common.dro.ChannelCountDRO;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.query.ChannelQuery;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.company.CompanyDRO;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.base.plat.engine.common.constant.CompanyConsts;
import com.zmn.base.plat.engine.common.constant.PlatEngineConsts;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.cube.common.dro.measure.MeasureDRO;
import com.zmn.cube.common.dro.menu.MenuDRO;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.mcc.business.interfaces.dept.DeptDpermitBService;
import com.zmn.mcc.business.interfaces.dpermit.account.DpermitPromotionBService;
import com.zmn.mcc.business.interfaces.dpermit.area.DpermitAreaBService;
import com.zmn.mcc.business.interfaces.dpermit.channel.DpermitChannelBService;
import com.zmn.mcc.business.interfaces.dpermit.company.DpermitCompanyBService;
import com.zmn.mcc.business.interfaces.dpermit.cube.DpermitCubeMenuBService;
import com.zmn.mcc.business.interfaces.dpermit.dept.DpermitDeptBService;
import com.zmn.mcc.business.interfaces.dpermit.measure.DpermitCubeMeasureBService;
import com.zmn.mcc.business.interfaces.dpermit.newchannel.DpermitNewChannelBService;
import com.zmn.mcc.business.interfaces.dpermit.product.DpermitProductGroupBService;
import com.zmn.mcc.business.interfaces.staff.StaffBService;
import com.zmn.mcc.cache.OrganizeCache;
import com.zmn.mcc.common.constant.DpermitConsts;
import com.zmn.mcc.common.dto.exception.MccException;
import com.zmn.mcc.manager.utils.DpermitUtil;
import com.zmn.mcc.model.dto.dpermit.DpermitCountDO;
import com.zmn.mcc.model.dto.dpermit.DpermitSimpleDO;
import com.zmn.mcc.model.entity.dept.McDept;
import com.zmn.mcc.model.entity.dept.McDeptDpermit;
import com.zmn.mcc.model.entity.dept.McDeptDpermitQuery;
import com.zmn.mcc.model.entity.organize.McOrganize;
import com.zmn.mcc.services.interfaces.dept.DeptDpermitService;
import com.zmn.mcc.services.interfaces.dept.DeptService;
import com.zmn.mcc.services.interfaces.organize.OrganizeService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author heguanghua
 * @since 2020/04/14 21:54
 */
@Service
public class DeptDpermitBServiceImpl implements DeptDpermitBService {
    protected Logger logger = LoggerFactory.getLogger(DeptDpermitBServiceImpl.class);

    // region Resource
    @Resource
    private DeptDpermitService deptDpermitService;
    @Resource
    private DpermitAreaBService dpermitAreaBService;
    @Resource
    private OrganizeService organizeService;
    @Resource
    private DeptService deptService;
    @Resource
    private DpermitDeptBService dpermitDeptBService;
    @Resource
    private DpermitChannelBService dpermitChannelBService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CompanyListRemoteService companyListRemoteService;
    @Resource
    private DpermitCompanyBService dpermitCompanyBService;
    @Resource
    private DpermitCubeMenuBService dpermitCubeMenuBService;
    @Resource
    private DpermitProductGroupBService dpermitProductGroupBService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ChannelListRemoteService channelListRemoteService;
    @Resource
    private StaffBService staffBService;
    @Resource
    private OrganizeCache organizeCache;
    @Resource
    private DpermitCubeMeasureBService dpermitCubeMeasureBService;
    @Resource
    private DpermitPromotionBService dpermitPromotionBService;
    @Resource
    private DpermitNewChannelBService dpermitNewChannelBService;
    // endregion


    // region 取得指定及其下级的数据权限列表

    @Override
    @ReadOnlyConnection
    public List<McDeptDpermit> listDpermitForSelfAndSub(Integer deptId, Integer dataType, List<Integer> dataParentIds) {

        // 本身列表
        McDeptDpermitQuery selfQuery = new McDeptDpermitQuery();
        selfQuery.setDeptId(deptId);
        selfQuery.setDataType(dataType);
        selfQuery.setDataIds(dataParentIds);
        List<McDeptDpermit> selfDpermits = deptDpermitService.listByQuery(selfQuery);

        // 下级列表
        McDeptDpermitQuery subQuery = new McDeptDpermitQuery();
        subQuery.setDeptId(deptId);
        subQuery.setDataType(dataType);
        subQuery.setDataParentIds(dataParentIds);
        List<McDeptDpermit> subDpermits = deptDpermitService.listByQuery(subQuery);

        // 合并
        for (McDeptDpermit subDpermit : subDpermits) {
            selfDpermits.add(subDpermit);
        }
        return selfDpermits;
    }
    // endregion

    // region 取得部门的全部组织数据权限列表

    @Override
    @ReadOnlyConnection
    public ResponseDTO listOrganizeDpermit(Integer deptId, Integer status) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        // endregion

        // 已分配的部门组织数据权限
        List<McDeptDpermit> deptDpermits = deptDpermitService.listByDeptIdAndDataType(deptId, DpermitConsts.TYPE_ORGANIZE);

        // 省、市、区县列表，已分配的区域数据权限选中
        List<DpermitSimpleDO> items = dpermitCompanyBService.listOrganizeAndDpermitChecked(status, deptDpermits);

        return ResponseDTO.success(items, "OK");
    }
    // endregion

    // region 取得部门的全部部门数据权限列表

    @Override
    @ReadOnlyConnection
    public ResponseDTO listDeptDpermit(Integer deptId, Integer status) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }

        McDept dept = deptService.findByKey(deptId);
        if (NumberUtil.isNullOrZero(dept.getOrgId())) {
            return ResponseDTO.fail("部门不属于任何组织，无法取得部门数据");
        }
        // endregion

        // 已分配的部门区域数据权限
        List<Integer> deptDpermitIds = deptDpermitService.listDataIdByDeptIdAndDataType(deptId, DpermitConsts.TYPE_DEPT);

        // 一级、二级、三级部门列表，已分配的部门数据权限选中
        List<DpermitSimpleDO> items = dpermitDeptBService.listDeptAndDpermitChecked(dept.getOrgId(), status, deptDpermitIds);

        return ResponseDTO.success(items, "OK");
    }
    // endregion

    // region 取得部门的全部区域数据权限列表

    @Override
    @ReadOnlyConnection
    public ResponseDTO listAreaDpermit(Integer deptId, Integer status) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        // endregion

        // 已分配的部门区域数据权限
        List<Integer> deptDpermitIds = deptDpermitService.listDataIdByDeptIdAndDataType(deptId, DpermitConsts.TYPE_AREA);

        // 省、市、区县列表，已分配的区域数据权限选中
        List<DpermitSimpleDO> items = dpermitAreaBService.listAreaAndDpermitChecked(status, deptDpermitIds);

        return ResponseDTO.success(items, "OK");
    }
    // endregion

    // region 取得部门的全部渠道数据权限列表

    @Override
    @ReadOnlyConnection
    public ResponseDTO listChannelDpermit(Integer deptId, Integer status) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        // endregion

        // 已分配的部门渠道数据权限
        List<McDeptDpermit> deptDpermits = deptDpermitService.listByDeptIdAndDataType(deptId, DpermitConsts.TYPE_COOPERATION);

        // 下单平台/一级渠道列表，已分配的平台数据权限选中
        List<DpermitSimpleDO> items = dpermitChannelBService.listChannelAndDpermitChecked(status, deptDpermits);

        return ResponseDTO.success(items, "OK");
    }
    // endregion

    @Override
    @ReadOnlyConnection
    public ResponseDTO listNewChannelDpermit(Integer deptId, Integer status) {
        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        // 已分配的部门渠道数据权限
        List<McDeptDpermit> deptDpermits = deptDpermitService.listByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CHANNEL);
        // 下单平台/一级渠道列表，已分配的平台数据权限选中
        List<DpermitSimpleDO> items = dpermitNewChannelBService.listNewChannelDpermitChecked(status, deptDpermits);
        return ResponseDTO.success(items, "OK");
    }

    @Override
    @ReadOnlyConnection
    public ResponseDTO listAccountDpermit(Integer deptId, Integer status) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        // endregion

        // 已分配的账户渠道数据权限
        List<McDeptDpermit> deptDpermits = deptDpermitService.listByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PROMOTION);

        // 下单平台/一级渠道列表，已分配的平台数据权限选中
        List<DpermitSimpleDO> items = dpermitPromotionBService.listPromotionDpermitChecked(status, deptDpermits);

        return ResponseDTO.success(items, "OK");
    }

    // region 取得部门的全部大数据报表数据权限列表

    @Override
    @ReadOnlyConnection
    public ResponseDTO listCubeDpermit(Integer deptId, Integer status, List<MenuDRO> menus) {

        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }

        // endregion

        // 已分配的部门大数据报表数据权限
        List<Integer> deptDpermitIds = deptDpermitService.listDataIdByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CUBE);

        // 一级、二级、三级大数据报表列表，已分配的报表数据权限选中
        List<DpermitSimpleDO> items = dpermitCubeMenuBService.listMenuAndDpermitChecked(status, deptDpermitIds, menus);

        return ResponseDTO.success(items, "OK");
    }
    // endregion


    // region 取得部门的全部产品权限数据权限列表


    @Override
    public ResponseDTO listProductDpermit(Integer deptId, Integer status) {
        // region 校验参数

        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }

        // endregion

        // 已分配的部门产品数据权限
        List<McDeptDpermit> deptDpermitIds = deptDpermitService.listByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PRODUCT);

        // 一级、二级、三级产品列表，已分配的产品数据权限选中
        List<DpermitSimpleDO> items = dpermitProductGroupBService.listProductGroupAndDpermitChecked(status, deptDpermitIds);

        return ResponseDTO.success(items, "OK");
    }
    // endregion


    // region 部门组织数据权限分配

    // region 分配平台、大区、子公司数据权限

    @Override
    @Transactional
    public ResponseDTO assignOrganizeDpermit(Integer deptId, List<Integer> dpermitIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 分配组织数据权限
            this.assignOrganizeDpermit(deptId, dpermitIds, operator);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],dpermitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],dpermitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 添加服务商数据权限

    @Override
    @Transactional
    public ResponseDTO addOrganizeDpermitForSp(Integer deptId, List<Integer> companyIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, companyIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 本次要添加的服务商，服务商的子公司组织ID(parent_id)不能为空 , GlobalDict.STATUS_ENABLE
            ResponseDTO<List<CompanyDRO>> responseDTO = companyListRemoteService.listByCompanyIdsAndStatus(companyIds, GlobalConsts.YES);
            List<CompanyDRO> companies = responseDTO.isSuccess() ?
                    responseDTO.getData().stream().filter(e -> Objects.equals(e.getStatus(), GlobalDict.STATUS_ENABLE)).collect(Collectors.toList()) : new ArrayList<>(1);

            // 本次有关的子公司组织ID
            Set<Integer> subOrgIds = new HashSet<>();

            //region 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            for (CompanyDRO company : companies) {

                if (company.getType() != CompanyConsts.COMPANY_TYPE_SERVICE || NumberUtil.isNullOrZero(company.getOrgThrId())) {
                    continue;
                }

                // 子公司组织ID
                subOrgIds.add(company.getOrgThrId());

                McDeptDpermit dpermit = new McDeptDpermit(deptId, DpermitConsts.TYPE_ORGANIZE, operator);
                dpermit.setDataId(company.getCompanyId());
                dpermit.setDataName(company.getName());
                dpermit.setDataParentId(company.getOrgThrId());     // 子公司组织ID
                dpermit.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_GRANDSON);
                dpermit.setCreateTime(now);
                dpermit.setDataSubAll(GlobalDict.YESNO_YES);
                dpermits.add(dpermit);
            }
            if (CollectionUtil.isNullOrEmpty(subOrgIds)) {
                return ResponseDTO.fail("没有有效且信息符合规范的服务商可添加，请检查组织架构关联");
            }

            // 服务商有关的子公司组织列表
            List<McOrganize> subOrganizes = organizeService.listByOrgIds(new ArrayList<Integer>(subOrgIds), GlobalDict.STATUS_ENABLE);
            for (McOrganize organize : subOrganizes) {

                McDeptDpermit dpermit = new McDeptDpermit(deptId, DpermitConsts.TYPE_ORGANIZE, operator);
                dpermit.setDataId(organize.getOrgId());
                dpermit.setDataName(organize.getOrgName());
                dpermit.setDataParentId(organize.getParentId());
                dpermit.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_SUB);
                dpermit.setCreateTime(now);
                dpermit.setDataSubAll(GlobalDict.YESNO_NO);
                dpermits.add(dpermit);
            }
            // endregion

            // 替换原数据并写入新数据
            deptDpermitService.insertByBatch(dpermits);

            // 重新分配平台/大区/子公司数据权限
            this.reAssignOrganizeDpermit(deptId, operator);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],companyIds:[%s],operator:[%s<%s>]",
                    deptId, companyIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],companyIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, companyIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 移除子公司及其服务商数据权限

    @Override
    @Transactional
    public ResponseDTO deleteOrganizeDpermit(Integer deptId, Integer orgId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(orgId)) {
            return ResponseDTO.fail("子公司组织");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 删除服务商数据权限
            McDeptDpermitQuery spQuery = new McDeptDpermitQuery();
            spQuery.setDeptId(deptId);
            spQuery.setDataType(DpermitConsts.TYPE_ORGANIZE);
            spQuery.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_GRANDSON);
            spQuery.setDataParentId(orgId);
            deptDpermitService.deleteByQuery(spQuery);

            // 删除子公司数据权限
            McDeptDpermitQuery subQuery = new McDeptDpermitQuery();
            subQuery.setDeptId(deptId);
            subQuery.setDataType(DpermitConsts.TYPE_ORGANIZE);
            spQuery.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_SUB);
            subQuery.setDataId(orgId);
            deptDpermitService.deleteByQuery(subQuery);

            // 重新分配平台/大区/子公司数据权限
            this.reAssignOrganizeDpermit(deptId, operator);

            logger.info(String.format("[ZMN]移除部门数据权限成功,deptId:[%s],orgId:[%s],operator:[%s<%s>]",
                    deptId, orgId, operator, operatorId));
            return ResponseDTO.success(null, "移除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]移除部门数据权限出错,deptId:[%s],orgId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, orgId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("移除部门数据权限失败");
        }
    }
    // endregion

    // region 移除指定服务商数据权限

    @Override
    @Transactional
    public ResponseDTO deleteOrganizeDpermitForSp(Integer deptId, Integer companyId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(companyId)) {
            return ResponseDTO.fail("未指定服务商");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 取得要删除的数据权限对象
            McDeptDpermitQuery findQuery = new McDeptDpermitQuery();
            findQuery.setDeptId(deptId);
            findQuery.setDataType(DpermitConsts.TYPE_ORGANIZE);
            findQuery.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_GRANDSON);
            findQuery.setDataId(companyId);
            McDeptDpermit dpermit = deptDpermitService.findByQuery(findQuery);
            if (dpermit == null) {
                return ResponseDTO.fail("没有找到要移除的数据权限");
            }

            // 删除服务商数据权限
            McDeptDpermitQuery deleteQuery = new McDeptDpermitQuery();
            deleteQuery.setDeptId(deptId);
            deleteQuery.setDataType(DpermitConsts.TYPE_ORGANIZE);
            deleteQuery.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_GRANDSON);
            deleteQuery.setDataId(companyId);
            int pos = deptDpermitService.deleteByQuery(deleteQuery);

            // 检查子公司下还有无服务商数据权限
            McDeptDpermitQuery spCountQuery = new McDeptDpermitQuery();
            spCountQuery.setDeptId(deptId);
            spCountQuery.setDataType(DpermitConsts.TYPE_ORGANIZE);
            spCountQuery.setDataLevel(DpermitConsts.ORGANIZE_LEVEL_GRANDSON);
            spCountQuery.setDataParentId(dpermit.getDataParentId());
            int count = deptDpermitService.countByQuery(spCountQuery);

            // 如已移除子公司下的全部服务商数据权限，重新分配平台/大区/子公司数据权限
            if (count == 0) {
                this.reAssignOrganizeDpermit(deptId, operator);
            }

            logger.info(String.format("[ZMN]移除部门数据权限成功,deptId:[%s],companyId:[%s],operator:[%s<%s>]",
                    deptId, companyId, operator, operatorId));
            return ResponseDTO.success(null, "移除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]移除部门数据权限出错,deptId:[%s],companyId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, companyId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("移除部门数据权限失败");
        }
    }
    // endregion

    // region 清除全部组织数据权限

    @Override
    public ResponseDTO clearOrganizeDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_ORGANIZE);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }

    @Override
    public ResponseDTO clearAccountDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }
        try {
            // 批量删除数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PROMOTION);

            logger.info(String.format("[ZMN]清除推广数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除推广数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除推广数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除推广数据权限失败");
        }
    }
    // endregion

    /**
     * 重新分配平台、大区、子公司数据权限
     *
     * @param deptId   部门ID
     * @param operator 操作人
     * @return
     */
    private void reAssignOrganizeDpermit(Integer deptId, String operator) {

        // 取得平台/大区/子公司数据权限ID集
        List<Integer> dpermitIds = deptDpermitService.listDataIdByDeptIdAndDataAttr(deptId, DpermitConsts.TYPE_ORGANIZE, DpermitConsts.ORGANIZE_LEVEL_PLAT_REGION_SUB);

        // 重新分配平台/大区/子公司数据权限
        this.assignOrganizeDpermit(deptId, dpermitIds, operator);
    }

    /**
     * 分配平台、大区、子公司数据权限
     *
     * @param deptId     部门ID
     * @param dpermitIds 数据权限ID
     * @param operator   操作人
     * @return
     */
    private void assignOrganizeDpermit(Integer deptId, List<Integer> dpermitIds, String operator) {

        // 子公司的服务商数据权限数集合
        McDeptDpermitQuery query = new McDeptDpermitQuery();
        query.setDeptId(deptId);
        query.setDataType(DpermitConsts.TYPE_ORGANIZE);
        List<DpermitCountDO> spCounts = deptDpermitService.countByQueryGroupByParentId(query);

        // 平台/大区/子公司的层级列表，要分配的组织已选中
        List<DpermitSimpleDO> organizes = dpermitCompanyBService.listOrganizeTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds, spCounts);

        // 创建要写入的数据权限对象集合
        Date now = DateUtil.getNow();
        List<McDeptDpermit> dpermits = new ArrayList<>();
        this.createDpermits(deptId, organizes, dpermits, DpermitConsts.TYPE_ORGANIZE, operator, now);

        // 批量删除原数据并写入新数据
        deptDpermitService.deleteByDeptIdAndDataAttr(deptId, DpermitConsts.TYPE_ORGANIZE, DpermitConsts.ORGANIZE_LEVEL_PLAT_REGION_SUB);
        deptDpermitService.insertByBatch(dpermits);
    }
    // endregion

    // region 部门部门数据权限分配

    // region 分配一级、二级、三级部门数据权限

    @Override
    @Transactional
    public ResponseDTO assignDeptDpermit(Integer deptId, List<Integer> dpermitIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            McDept dept = deptService.findByKey(deptId);
            if (NumberUtil.isNullOrZero(dept.getOrgId())) {
                return ResponseDTO.fail("部门不属于任何组织，不能分配部门数据权限");
            }

            // 三级部门层级列表，要分配的部门已选中
            List<DpermitSimpleDO> depts = dpermitDeptBService.listDeptTreeAndDpermitChecked(dept.getOrgId(), GlobalDict.STATUS_ENABLE, dpermitIds);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, depts, dpermits, DpermitConsts.TYPE_DEPT, operator, now);

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_DEPT);
            deptDpermitService.insertByBatch(dpermits);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 清除全部部门数据权限

    @Override
    public ResponseDTO clearDeptDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_DEPT);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }
    // endregion
    // endregion

    // region 部门区域数据权限分配

    // region 分配省、市、区县数据权限

    @Override
    @Transactional
    public ResponseDTO assignAreaDpermit(Integer deptId, List<Integer> dpermitIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 区县及以上区域层级列表，要分配的区域已选中
            List<DpermitSimpleDO> provinces = dpermitAreaBService.listAreaTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, provinces, dpermits, DpermitConsts.TYPE_AREA, operator, now);

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_AREA);
            deptDpermitService.insertByBatch(dpermits);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 清除全部区域数据权限

    @Override
    public ResponseDTO clearAreaDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_AREA);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }
    // endregion
    // endregion

    // region 部门渠道数据权限分配

    // region 分配下单平台数据权限

    @Override
    @Transactional
    public ResponseDTO assignChannelDpermitForPlat(Integer deptId, List<Integer> dpermitIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 分配下单平台数据权限
            this.assignChannelPlatDpermit(deptId, dpermitIds, operator);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],dpermitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],dpermitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 添加渠道数据权限

    @Override
    @Transactional
    public ResponseDTO addChannelDpermit(Integer deptId, List<Integer> channelIds, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, channelIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 本次操作有关的下单平台标识/一级渠道ID/渠道对象Map
            Set<Integer> plats = new HashSet<>();
            Set<Integer> oneChannelIds = new HashSet<>();
            Map<Integer, ChannelDRO> channelMap = new HashMap<>(16);

            // 本次要添加的渠道
            List<ChannelDRO> channels = listChannelByChannelIdsAndStatus(channelIds, GlobalDict.STATUS_ENABLE);
            for (ChannelDRO channel : channels) {
                if (channel.getRank() == null || channel.getPlat() == null) {
                    continue;
                }
                plats.add(channel.getPlat().intValue());
                if (channel.getRank() == DpermitConsts.COOPERATION_LEVEL_COMPANY - 1) {
                    oneChannelIds.add(channel.getChannelId());
                } else if (channel.getRank() == DpermitConsts.COOPERATION_LEVEL_CHANNEL - 1) {
                    oneChannelIds.add(channel.getParentId());
                }
                channelMap.put(channel.getChannelId(), channel);
            }
            List<ChannelDRO> oneChannels = listChannelByChannelIdsAndStatus(new ArrayList<>(oneChannelIds), GlobalDict.STATUS_ENABLE);
            for (ChannelDRO channel : oneChannels) {
                channelMap.put(channel.getChannelId(), channel);
            }
            if (CollectionUtil.isNullOrEmpty(plats)) {
                return ResponseDTO.fail("没有有效且信息符合规范的渠道可添加");
            }

            //region 创建要写入的数据权限对象集合

            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            for (ChannelDRO channel : channelMap.values()) {
                McDeptDpermit dpermit = new McDeptDpermit(deptId, DpermitConsts.TYPE_COOPERATION, operator);
                dpermit.setDataId(channel.getChannelId());
                dpermit.setDataName(channel.getName());
                dpermit.setDataParentId(channel.getRank() == DpermitConsts.COOPERATION_LEVEL_COMPANY - 1   // 一级渠道的parentId为plat
                        ? channel.getPlat() : channel.getParentId());
                dpermit.setDataLevel((channel.getRank() + 1));
                dpermit.setCreateTime(now);
                dpermit.setDataSubAll(channel.getRank() == DpermitConsts.COOPERATION_LEVEL_CHANNEL - 1
                        ? GlobalDict.YESNO_YES : GlobalDict.YESNO_NO);
                dpermits.add(dpermit);
            }
            // endregion

            // 写入本次添加的数据权限(如存在则替换，一级渠道全选状态未明，先写入，再重新计算相关选择状态)
            deptDpermitService.insertByBatch(dpermits);

            // 重新分配相关一级渠道及其下级渠道的数据权限
            this.assignChannelDpermit(deptId, new ArrayList<Integer>(oneChannelIds), GlobalDict.STATUS_ENABLE, operator);

            // 添加下单平台数据权限(如存在则替换)
            this.addChannelPlatDpermit(deptId, new ArrayList<Integer>(plats), operator);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],channelIds:[%s],operator:[%s<%s>]",
                    deptId, channelIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],channelIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, channelIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 移除指定平台及其渠道数据权限

    @Override
    @Transactional
    public ResponseDTO deleteChannelDpermit(Integer deptId, Integer plat, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(plat)) {
            return ResponseDTO.fail("未指定下单平台");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 取得下单平台的一级渠道ID列表
            McDeptDpermitQuery query = new McDeptDpermitQuery();
            query.setDeptId(deptId);
            query.setDataType(DpermitConsts.TYPE_COOPERATION);
            query.setDataLevel(DpermitConsts.COOPERATION_LEVEL_PLAT);
            query.setDataParentId(plat.intValue());
            List<Integer> oneChannelIds = deptDpermitService.listDataIdByQuery(query);

            // 删除下单平台数据权限
            McDeptDpermitQuery platQuery = new McDeptDpermitQuery();
            platQuery.setDeptId(deptId);
            platQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
            platQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_PLAT);
            platQuery.setDataId(plat.intValue());
            deptDpermitService.deleteByQuery(platQuery);

            // 删除二级渠道数据权限
            if (CollectionUtil.isNotNullOrEmpty(oneChannelIds)) {
                McDeptDpermitQuery twoQuery = new McDeptDpermitQuery();
                twoQuery.setDeptId(deptId);
                twoQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
                twoQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_CHANNEL);
                twoQuery.setDataParentIds(oneChannelIds);
                deptDpermitService.deleteByQuery(twoQuery);
            }

            // 删除一级级渠道数据权限
            if (CollectionUtil.isNotNullOrEmpty(oneChannelIds)) {
                McDeptDpermitQuery oneQuery = new McDeptDpermitQuery();
                oneQuery.setDeptId(deptId);
                oneQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
                oneQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_COMPANY);
                oneQuery.setDataIds(oneChannelIds);
                deptDpermitService.deleteByQuery(oneQuery);
            }

            logger.info(String.format("[ZMN]移除部门数据权限成功,deptId:[%s],plat:[%s],operator:[%s<%s>]",
                    deptId, plat, operator, operatorId));
            return ResponseDTO.success(null, "移除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]移除部门数据权限出错,deptId:[%s],plat:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, plat, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("移除部门数据权限失败");
        }
    }
    // endregion

    // region 移除指定渠道(一级、二级渠道)数据权限

    @Override
    @Transactional
    public ResponseDTO deleteChannelDpermit(Integer deptId, List<Integer> channelIds, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (CollectionUtil.isNullOrEmpty(channelIds)) {
            return ResponseDTO.fail("未指定渠道");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 本次操作有关的下单平台标识/一级渠道ID/直接一级渠道ID/间接一级渠道ID
            Set<Integer> plats = new HashSet<>();
            Set<Integer> oneChannelIds = new HashSet<>();
            Set<Integer> directOneChannelIds = new HashSet<>();
            Set<Integer> indirectOneChannelIds = new HashSet<>();

            // 本次要删除的渠道
            List<ChannelDRO> channels = listChannelByChannelIdsAndStatus(channelIds, GlobalDict.STATUS_ENABLE);
            for (ChannelDRO channel : channels) {
                if (channel.getRank() == null || channel.getPlat() == null) {
                    continue;
                }
                plats.add(channel.getPlat().intValue());
                if (channel.getRank() == DpermitConsts.COOPERATION_LEVEL_COMPANY - 1) {
                    oneChannelIds.add(channel.getChannelId());
                    directOneChannelIds.add(channel.getChannelId());
                } else if (channel.getRank() == DpermitConsts.COOPERATION_LEVEL_CHANNEL - 1) {
                    oneChannelIds.add(channel.getParentId());
                }
            }

            // 计算间接一级渠道ID
            for (int oneChannelId : oneChannelIds) {
                if (!directOneChannelIds.contains(oneChannelId)) {
                    indirectOneChannelIds.add(oneChannelId);
                }
            }

            // 删除原直接一级渠道权限数据
            if (CollectionUtil.isNotNullOrEmpty(directOneChannelIds)) {
                McDeptDpermitQuery selfQuery = new McDeptDpermitQuery();
                selfQuery.setDeptId(deptId);
                selfQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
                selfQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_COMPANY);
                selfQuery.setDataIds(new ArrayList<>(directOneChannelIds));
                deptDpermitService.deleteByQuery(selfQuery);
            }

            // 删除原直接一级渠道的下级渠道权限数据
            if (CollectionUtil.isNotNullOrEmpty(directOneChannelIds)) {
                McDeptDpermitQuery subQuery = new McDeptDpermitQuery();
                subQuery.setDeptId(deptId);
                subQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
                subQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_CHANNEL);
                subQuery.setDataParentIds(new ArrayList<>(directOneChannelIds));
                deptDpermitService.deleteByQuery(subQuery);
            }

            // 删除渠道(先删除，再重新计算相关选择状态)
            if (CollectionUtil.isNotNullOrEmpty(channelIds)) {
                McDeptDpermitQuery deleteQuery = new McDeptDpermitQuery();
                deleteQuery.setDeptId(deptId);
                deleteQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
                deleteQuery.setDataIds(channelIds);
                deptDpermitService.deleteByQuery(deleteQuery);
            }

            // 重新分配指定一级渠道及其下级渠道的数据权限(直接移除二级渠道数据权限时)
            if (CollectionUtil.isNotNullOrEmpty(indirectOneChannelIds)) {
                this.assignChannelDpermit(deptId, new ArrayList<Integer>(indirectOneChannelIds), GlobalDict.STATUS_ENABLE, operator);
            }

            // 重新分配下单平台数据权限
            this.reAssignChannelPlatDpermit(deptId, operator);

            logger.info(String.format("[ZMN]移除部门数据权限成功,deptId:[%s],channelIds:[%s],operator:[%s<%s>]",
                    deptId, channelIds, operator, operatorId));
            return ResponseDTO.success(null, "移除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]移除部门数据权限出错,deptId:[%s],channelIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, channelIds, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("移除部门数据权限失败");
        }
    }
    // endregion

    // region 清除全部渠道(下单平台、一级、二级渠道)数据权限

    @Override
    public ResponseDTO clearChannelDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_COOPERATION);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }
    // endregion

    /**
     * 重新分配下单平台数据权限
     *
     * @param deptId   部门ID
     * @param operator 操作人
     * @return
     */
    private void reAssignChannelPlatDpermit(Integer deptId, String operator) {

        // 取得下单平台数据权限ID集
        List<Integer> dpermitIds = deptDpermitService.listDataIdByDeptIdAndDataAttr(deptId, DpermitConsts.TYPE_COOPERATION, Arrays.asList(DpermitConsts.COOPERATION_LEVEL_PLAT));

        // 重新分配下单平台数据权限
        this.assignChannelPlatDpermit(deptId, dpermitIds, operator);
    }

    /**
     * 分配下单平台数据权限
     *
     * @param deptId   部门ID
     * @param plats    数据权限ID(平台plat标识)
     * @param operator 操作人
     * @return
     */
    private void assignChannelPlatDpermit(Integer deptId, List<Integer> plats, String operator) {

        // 每个平台的一级渠道数量<plat,count>
        List<DpermitCountDO> dpermitCounts = this.listDpermitCountForChannelPlat(deptId);

        // 下单平台/一级渠道层级列表，要分配的平台/渠道已选中
        List<DpermitSimpleDO> channelPlats = dpermitChannelBService.listChannelPlatAndDpermitChecked(GlobalDict.STATUS_ENABLE, plats, dpermitCounts);

        // 创建要写入的数据权限对象集合
        Date now = DateUtil.getNow();
        List<McDeptDpermit> dpermits = new ArrayList<>();
        this.createDpermits(deptId, channelPlats, dpermits, DpermitConsts.TYPE_COOPERATION, operator, now);

        // 批量删除原数据并写入新数据
        deptDpermitService.deleteByDeptIdAndDataAttr(deptId, DpermitConsts.TYPE_COOPERATION, Arrays.asList(DpermitConsts.COOPERATION_LEVEL_PLAT));
        deptDpermitService.insertByBatch(dpermits);
    }

    /**
     * 添加下单平台数据权限
     *
     * @param deptId
     * @param plats    数据权限ID(平台plat标识)
     * @param operator
     */
    private void addChannelPlatDpermit(Integer deptId, List<Integer> plats, String operator) {

        // 每个平台的一级渠道数量<plat,count>
        List<DpermitCountDO> counts = this.listDpermitCountForChannelPlat(deptId);
        Map<Integer, Integer> countMap = new HashMap<>(16);
        for (DpermitCountDO count : counts) {
            countMap.put(count.getDataId(), count.getCount());
        }

        // 平台kv列表
        Map<Integer, String> platMap = organizeCache.getPlatMap();

        //region 创建要写入的数据权限对象集合
        Date now = DateUtil.getNow();
        List<McDeptDpermit> dpermits = new ArrayList<>();
        for (int plat : plats) {
            McDeptDpermit dpermit = new McDeptDpermit(deptId, DpermitConsts.TYPE_COOPERATION, operator);
            dpermit.setDataId(plat);
            dpermit.setDataName(platMap.get(plat));
            dpermit.setDataParentId(GlobalConsts.TOP_ID);
            dpermit.setDataLevel(DpermitConsts.COOPERATION_LEVEL_PLAT);
            dpermit.setCreateTime(now);
            dpermit.setDataSubAll(Optional.ofNullable(countMap.get(plat)).orElse(0) == 0
                    ? GlobalDict.YESNO_YES : GlobalDict.YESNO_NO);    // 有一级渠道即为no
            dpermits.add(dpermit);
        }
        // endregion

        // 写入新数据(如存在则替换)
        deptDpermitService.insertByBatch(dpermits);
    }

    /**
     * 分配指定一级渠道及其下级渠道的数据权限
     *
     * @param deptId
     * @param oneChannelIds 数据权限ID(一级渠道ID)
     * @param status
     * @return
     */
    private void assignChannelDpermit(Integer deptId, List<Integer> oneChannelIds, Integer status, String operator) {

        List<DpermitSimpleDO> simples = new ArrayList<>();

        // 一级渠道ID与简单数据权限对象的映射关系
        Map<Integer, DpermitSimpleDO> map = new HashMap<>(16);

        //region 取得一级/二级渠道的数据权限对象集合
        List<McDeptDpermit> deptDpermits = this.listDpermitForSelfAndSub(deptId, DpermitConsts.TYPE_COOPERATION, oneChannelIds);
        for (McDeptDpermit dpermit : deptDpermits) {

            // 简单数据权限对象
            DpermitSimpleDO simple = DpermitUtil.parseToDpermitSimpleDO(dpermit);

            // 一级渠道加入映射关系map
            if (simple.getLevel() == DpermitConsts.COOPERATION_LEVEL_COMPANY) {
                map.put(simple.getDataId(), simple);
            }

            // 设置选择状态
            simple.setChecked(true);
            if (simple.getLevel() == DpermitConsts.COOPERATION_LEVEL_CHANNEL) {
                simple.setSubAll(true);
            }

            // 一级渠道加入主列表
            if (simple.getLevel() == DpermitConsts.COOPERATION_LEVEL_COMPANY) {
                simples.add(simple);
            }
            // 二级渠道加入一级渠道的子集
            else if (simple.getLevel() == DpermitConsts.COOPERATION_LEVEL_CHANNEL) {
                DpermitSimpleDO parent = map.get(simple.getParentId());
                if (parent != null) {
                    parent.getSubors().add(simple);
                }
            }
        }
        // endregion

        //region 本次相关的一级渠道及其下级渠道数量
        Map<Integer, Integer> countMap = new HashMap<>(16);
        ResponseDTO<List<ChannelCountDRO>> responseDTO = channelListRemoteService.listCountByStatusAndChannelIdsGroupByParentId(oneChannelIds, status);
        List<ChannelCountDRO> channelCounts = new ArrayList<>();
        if (responseDTO.isSuccess()) {
            channelCounts.addAll(responseDTO.getData());
        }
        for (ChannelCountDRO channelCount : channelCounts) {
            countMap.put(channelCount.getDataId(), channelCount.getCount());
        }
        // endregion

        // region 检查计算一级渠道选中状态
        for (DpermitSimpleDO simple : simples) {
            int checkedCount = simple.getSubors().size();
            if (checkedCount > 0) {
                simple.setChecked(true);
            }
            if (simple.isChecked()) {
                if (checkedCount == 0) {
                    simple.setSubAll(true);
                } else {
                    Integer count = countMap.get(simple.getDataId());
                    simple.setSubAll(count != null && count == checkedCount);
                }
            }
        }
        // endregion

        // 创建要写入的数据权限对象集合
        Date now = DateUtil.getNow();
        List<McDeptDpermit> dpermits = new ArrayList<>();
        this.createDpermits(deptId, simples, dpermits, DpermitConsts.TYPE_COOPERATION, operator, now);

        // 删除原一级渠道权限数据
        if (CollectionUtil.isNotNullOrEmpty(oneChannelIds)) {
            McDeptDpermitQuery selfQuery = new McDeptDpermitQuery();
            selfQuery.setDeptId(deptId);
            selfQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
            selfQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_COMPANY);
            selfQuery.setDataIds(oneChannelIds);
            deptDpermitService.deleteByQuery(selfQuery);
        }

        // 删除原二级渠道权限数据
        if (CollectionUtil.isNotNullOrEmpty(oneChannelIds)) {
            McDeptDpermitQuery subQuery = new McDeptDpermitQuery();
            subQuery.setDeptId(deptId);
            subQuery.setDataType(DpermitConsts.TYPE_COOPERATION);
            subQuery.setDataLevel(DpermitConsts.COOPERATION_LEVEL_CHANNEL);
            subQuery.setDataParentIds(oneChannelIds);
            deptDpermitService.deleteByQuery(subQuery);
        }

        // 写入新数据权限
        deptDpermitService.insertByBatch(dpermits);
    }

    /**
     * 取得每个平台的一级渠道数量
     *
     * @param deptId 部门ID
     * @return DpermitCountDO<plat, count>
     */
    private List<DpermitCountDO> listDpermitCountForChannelPlat(Integer deptId) {
        McDeptDpermitQuery query = new McDeptDpermitQuery();
        query.setDeptId(deptId);
        query.setDataType(DpermitConsts.TYPE_COOPERATION);
        query.setDataLevel(DpermitConsts.COOPERATION_LEVEL_COMPANY);
        return deptDpermitService.countByQueryGroupByParentId(query);
    }
    // endregion

    // region 部门大数据报表数据权限分配

    // region 分配一级、二级、三级大数据报表数据权限

    @Override
    @Transactional
    public ResponseDTO assignCubeDpermit(Integer deptId, List<Integer> dpermitIds, List<MenuDRO> menus, Integer operatorId, String operator) {

        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 三级大数据报表层级列表，要分配的报表已选中
            List<DpermitSimpleDO> depts = dpermitCubeMenuBService.listMenuTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds, menus);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, depts, dpermits, DpermitConsts.TYPE_CUBE, operator, now);

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CUBE);
            deptDpermitService.insertByBatch(dpermits);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }
    // endregion

    // region 清除全部大数据报表数据权限

    @Override
    public ResponseDTO clearCubeDpermit(Integer deptId, Integer operatorId, String operator) {

        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CUBE);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }
    // endregion
    // endregion


    // region 部门产品数据权限分配

    // region 分配一级、二级、三级产品数据权限

    @Override
    public ResponseDTO assignProductDpermit(Integer deptId, List<String> dpermitIds, Integer operatorId, String operator) {
        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 要分配的已选中
            List<DpermitSimpleDO> productGroupDOList = dpermitProductGroupBService.listProductGroupTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, productGroupDOList, dpermits, DpermitConsts.TYPE_PRODUCT, operator, now);

            if (CollectionUtils.isNotEmpty(dpermits)) {
                // 批量删除原数据并写入新数据
                deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PRODUCT);
                deptDpermitService.insertByBatch(dpermits);

                logger.info(String.format("[ZMN]修改部门产品数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                        deptId, dpermitIds.toString(), operator, operatorId));
                return ResponseDTO.success(null, "修改部门产品数据权限成功");
            }


        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门产品数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门产品数据权限失败");
        }
        logger.info(String.format("[ZMN]修改部门产品数据权限失败，无相应的数据,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                deptId, dpermitIds.toString(), operator, operatorId));
        return ResponseDTO.fail("修改部门产品数据权限失败");
    }

    // endregion

    // region 清除全部产品数据权限

    @Override
    public ResponseDTO clearProductDpermit(Integer deptId, Integer operatorId, String operator) {
        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PRODUCT);

            logger.info(String.format("[ZMN]清除部门产品数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门产品数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门产品数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门产品数据权限失败");
        }
    }

    @Override
    public ResponseDTO listMeasureDpermit(Integer deptId, int status, List<MeasureDRO> measures) {
        // 必须指定部门ID
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }

        // 已分配的部门大数据报表指标数据权限
        List<Integer> deptDpermitIds = deptDpermitService.listDataIdByDeptIdAndDataType(deptId, DpermitConsts.TYPE_MEASURE);

        // 一级、二级、三级大数据报表指标列表，已分配的指标数据权限选中
        List<DpermitSimpleDO> items = dpermitCubeMeasureBService.listMeasureAndDpermitChecked(status, deptDpermitIds, measures);

        return ResponseDTO.success(items, "OK");
    }

    @Override
    public ResponseDTO assignMeasureDpermit(Integer deptId, List<Integer> dpermitIds, List<MeasureDRO> measures, Integer operatorId, String operator) {
        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 三级大数据指标层级列表，要分配的指标已选中
            List<DpermitSimpleDO> depts = dpermitCubeMeasureBService.listMeasureTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds, measures);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, depts, dpermits, DpermitConsts.TYPE_MEASURE, operator, now);

            // 批量删除原数据并写入新数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_MEASURE);
            deptDpermitService.insertByBatch(dpermits);

            logger.info(String.format("[ZMN]修改部门数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                    deptId, dpermitIds.toString(), operator, operatorId));
            return ResponseDTO.success(null, "修改部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门数据权限失败");
        }
    }

    @Override
    public ResponseDTO clearMeasureDpermit(Integer deptId, Integer operatorId, String operator) {
        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 批量删除原数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_MEASURE);

            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }


    // endregion
    // endregion


    // region 校验必要参数

    /**
     * 校验必要参数
     *
     * @param deptId
     * @param dpermitIds
     * @param operatorId
     * @return
     */
    private ResponseDTO checkParams(Integer deptId, List<?> dpermitIds, Integer operatorId) {

        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (CollectionUtil.isNullOrEmpty(dpermitIds)) {
            return ResponseDTO.fail("未指定要分配的权限");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }

        return ResponseDTO.success(null, "OK");
    }
    // endregion

    // region 员工是否拥有"系统全局角色"

    /**
     * 员工是否拥有"系统全局角色"
     *
     * @param operatorId
     * @return
     */
    private ResponseDTO checkRole(Integer operatorId) {

        // 员工是否拥有"系统全局角色"
        boolean isGlobalAdmin = staffBService.isGlobalAdmin(operatorId);
        if (!isGlobalAdmin) {
            return ResponseDTO.fail("您没有权限修改部门数据权限");
        }

        return ResponseDTO.success(null, "OK");
    }
    // endregion

    // region 创建要写入的数据权限对象集合

    /**
     * 创建要写入的数据权限对象集合
     * 如下级全部选中，则过滤所有下级
     *
     * @param deptId     部门ID
     * @param simples    当前的简单数据权限对象集合
     * @param dpermits   要写入的数据权限对象集合
     * @param dataType   数据权限类型
     * @param operator   操作人
     * @param createTime 操作时间
     */
    private void createDpermits(Integer deptId, List<DpermitSimpleDO> simples, List<McDeptDpermit> dpermits, Integer dataType, String operator, Date createTime) {

        for (DpermitSimpleDO simple : simples) {

            if (simple.isChecked()) {
                McDeptDpermit dpermit = new McDeptDpermit();
                dpermit.setDeptId(deptId);
                dpermit.setDataType(dataType);
                dpermit.setDataId(simple.getDataId());
                dpermit.setDataName(simple.getDataName());
                dpermit.setDataParentId(simple.getParentId());
                dpermit.setDataLevel(simple.getLevel());
                dpermit.setCreater(operator);
                dpermit.setCreateTime(createTime);
                dpermit.setDataSubAll(simple.isSubAll() ? GlobalDict.YESNO_YES : GlobalDict.YESNO_NO);
                dpermits.add(dpermit);
            }

            // 如下级全部选中，则过滤所有下级
            if (CollectionUtil.isNullOrEmpty(simple.getSubors()) || simple.isSubAll()) {
                continue;
            }

            // 迭代下级
            this.createDpermits(deptId, simple.getSubors(), dpermits, dataType, operator, createTime);
        }
    }
    // endregion


    // region 通过渠道id查询渠道基本信息
    private List<ChannelDRO> listChannelByChannelIdsAndStatus(List<Integer> channelIds, Integer status) {
        ChannelQuery channelDIOInner = new ChannelQuery();
        channelDIOInner.setChannelIds(channelIds);
        channelDIOInner.setStatus(status);
        ResponseDTO<List<ChannelDRO>> innerResponsDTO = channelListRemoteService.listByQuery(channelDIOInner);
        List<ChannelDRO> oneChannels = new ArrayList<>();
        if (innerResponsDTO.isSuccess()) {
            oneChannels.addAll(innerResponsDTO.getData());
        }
        return oneChannels;
    }


    @Override
    public ResponseDTO addPromotionDpermit(Integer deptId, List<Integer> dpermitIds, List<Integer> account, Integer operatorId, String operator, Integer type) {
        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }

        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }

        try {

            // 要分配的已选中
            List<DpermitSimpleDO> productGroupDOList = dpermitPromotionBService.listPromotionTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds, account, type);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, productGroupDOList, dpermits, DpermitConsts.TYPE_PROMOTION, operator, now);

            if (CollectionUtils.isNotEmpty(dpermits)) {
                // 批量删除原数据并写入新数据
                if (!Objects.equals(PlatEngineConsts.YES, type)) {
                    deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_PROMOTION);
                }
                deptDpermitService.insertByBatch(dpermits);

                logger.info(String.format("[ZMN]修改部门产品数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                        deptId, dpermitIds.toString(), operator, operatorId));
                return ResponseDTO.success(null, "修改部门产品数据权限成功");
            }


        } catch (MccException ex) {
            return ResponseDTO.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门产品数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门产品数据权限失败");
        }
        logger.info(String.format("[ZMN]修改部门产品数据权限失败，无相应的数据,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                deptId, dpermitIds.toString(), operator, operatorId));
        return ResponseDTO.fail("修改部门产品数据权限失败");
    }

    @Override
    public ResponseDTO addNewChannelDpermit(Integer deptId, List<Integer> dpermitIds, Integer operatorId, String operator) {
        // 校验参数
        ResponseDTO checkResult = this.checkParams(deptId, dpermitIds, operatorId);
        if (!checkResult.isSuccess()) {
            return checkResult;
        }
        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }
        try {
            // 要分配的已选中
            List<DpermitSimpleDO> productGroupDOList = dpermitNewChannelBService.listNewChannelTreeAndDpermitChecked(GlobalDict.STATUS_ENABLE, dpermitIds);

            // 创建要写入的数据权限对象集合
            Date now = DateUtil.getNow();
            List<McDeptDpermit> dpermits = new ArrayList<>();
            this.createDpermits(deptId, productGroupDOList, dpermits, DpermitConsts.TYPE_CHANNEL, operator, now);

            if (CollectionUtils.isNotEmpty(dpermits)) {
                // 批量删除原数据并写入新数据
                deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CHANNEL);
                deptDpermitService.insertByBatch(dpermits);

                logger.info(String.format("[ZMN]修改部门新渠道数据权限成功,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                        deptId, dpermitIds.toString(), operator, operatorId));
                return ResponseDTO.success(null, "修改部门新渠道数据权限成功");
            }
        } catch (MccException ex) {
            return ResponseDTO.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改部门新渠道数据权限出错,deptId:[%s],permitIds:[%s],operator:[%s<%s>],ex:[%s]",
                    deptId, dpermitIds.toString(), operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("修改部门新渠道数据权限失败");
        }
        logger.info(String.format("[ZMN]修改部门新渠道数据权限失败，无相应的数据,deptId:[%s],permitIds:[%s],operator:[%s<%s>]",
                deptId, dpermitIds.toString(), operator, operatorId));
        return ResponseDTO.fail("修改部门新渠道数据权限失败");
    }

    @Override
    public ResponseDTO clearNewChannelDpermit(Integer deptId, Integer operatorId, String operator) {
        // 校验参数
        if (NumberUtil.isNullOrZero(deptId)) {
            return ResponseDTO.fail("未指定部门");
        }
        if (NumberUtil.isNullOrZero(operatorId)) {
            return ResponseDTO.fail("没有操作人");
        }
        // 校验员工是否拥有"系统全局角色"
        ResponseDTO roleResult = this.checkRole(operatorId);
        if (!roleResult.isSuccess()) {
            return roleResult;
        }
        try {
            // 批量删除数据
            deptDpermitService.deleteByDeptIdAndDataType(deptId, DpermitConsts.TYPE_CHANNEL);
            logger.info(String.format("[ZMN]清除部门数据权限成功,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId));
            return ResponseDTO.success(null, "清除部门数据权限成功");
        } catch (Exception ex) {
            logger.error(String.format("[ZMN]清除部门数据权限出错,deptId:[%s],operator:[%s<%s>]",
                    deptId, operator, operatorId, ex.getMessage()));
            return ResponseDTO.fail("清除部门数据权限失败");
        }
    }
}
